const canvas = document.querySelector("#canvas");
const context = canvas.getContext("2d");
const pushAnimationTimer = new AnimationTimer();
const fallingAnimationTimer = new AnimationTimer();
const LEFT = 2;
const fps = 60;
const BALL_RADIUS = 25;
const LEDGE_LEFT = 220;
const LEDGE_WIDTH = 100;
const GRAVITY_FORCE = 9.81; //9.81 m/s
const LEDGE_TOP = 55;
const PLATFORM_HEIGHT_IN_METERS = 2;
const pixelsPerMeter = (canvas.height - LEDGE_TOP) / PLATFORM_HEIGHT_IN_METERS;
let arrow = null;

const moveBall = {
    lastFrameTime: null,
    execute(sprite, context, time) {
        const now = +new Date();
        if (!this.lastFrameTime) {
            this.lastFrameTime = now;
            return;
        }
        if (pushAnimationTimer.isRunning()) {
            if (arrow === LEFT) {
                sprite.left -= sprite.velocityX / fps;
            } else {
                sprite.left += sprite.velocityX / fps;
            }
            if (isBallOnLedge()) {
                if (pushAnimationTimer.getElapsedTime() > 300) {
                    pushAnimationTimer.stop();
                }
            } else if (!fallingAnimationTimer.isRunning()) {
                startFalling();
                this.lastFrameTime = now;
            }

            if (fallingAnimationTimer.isRunning()) {
                sprite.top += sprite.velocityY / fps;
                sprite.velocityY =
                    GRAVITY_FORCE *
                    (fallingAnimationTimer.getElapsedTime() / 1000) *
                    pixelsPerMeter;
                if (sprite.top > canvas.height) {
                    // stopFalling();
                }
            }
        }
    }
};

const ledge = new Sprite("ledge", {
    paint(sprite, context) {
        context.save();
        context.shadowColor = "rgba(0,0,0,0.5)";
        context.shadowBlur = 8;
        context.shadowOffsetX = 2;
        context.shadowOffsetY = 2;

        context.fillStyle = "rgba(255,255,255,0.6)";
        context.strokeStyle = "rgba(0,0,0,0.6)";
        context.beginPath();
        context.rect(sprite.left, sprite.top, sprite.width, sprite.height);
        context.fill();
        context.stroke();
        context.restore();
    }
});

const ball = new Sprite(
    "ball",
    {
        paint(sprite, context) {
            context.save();
            context.shadowColor = "rgba(0,0,0,0.5)";
            context.shadowBlur = 8;
            context.shadowOffsetX = 2;
            context.shadowOffsetY = 2;

            context.fillStyle = "rgba(0,255,0,0.6)";
            context.strokeStyle = "rgba(0,0,255,0.6)";
            context.beginPath();
            context.arc(
                sprite.left,
                sprite.top,
                sprite.radius,
                0,
                Math.PI * 2,
                false
            );
            context.fill();
            context.stroke();
            context.restore();
        }
    },
    [moveBall]
);

function animate(time) {
    context.clearRect(0, 0, canvas.width, canvas.height);

    ball.update(context, time);
    ledge.update(context, time);

    ledge.paint(context);
    ball.paint(context);

    requestAnimationFrame(animate);
}

function isBallOnLedge() {
    return (
        ball.left + BALL_RADIUS > LEDGE_LEFT &&
        ball.left < LEDGE_LEFT + LEDGE_WIDTH
    );
}

ledge.left = LEDGE_LEFT;
ledge.top = 100;
ledge.width = LEDGE_WIDTH;

ball.left = 300;
ball.top = 74;
ball.radius = BALL_RADIUS;
ball.velocityX = 110;
ball.velocityY = 0;

function pushBallLeft() {
    if (pushAnimationTimer.isRunning()) {
        pushAnimationTimer.stop();
    }
    arrow = LEFT;
    pushAnimationTimer.start();
}

function startFalling() {
    fallingAnimationTimer.start();
    ball.velocityY = 0;
}

const btnThruster = document.querySelector("#thruster");
btnThruster.addEventListener("mousedown", e => {
    pushBallLeft();
});
requestAnimationFrame(animate);
